import socket
import cv2
import numpy as np
import os
import threading
import time

def handle_client(conn, addr):
    print(f"客户端 {addr} 已连接.")
    client_dir = f'received_images/{addr[0]}_{addr[1]}'
    os.makedirs(client_dir, exist_ok=True)
    save_interval = 20  # 保存间隔时间（秒）
    last_save_time = time.time()

    try:
        while True:
            length = recvall(conn, 16)  # 接收数据长度
            if not length:
                break
            string_data = recvall(conn, int(length))
            data = np.frombuffer(string_data, dtype='uint8')

            frame = cv2.imdecode(data, cv2.IMREAD_COLOR)
            cv2.imshow(f'服务器接收到的图像 - {addr}', frame)

            # 每隔20秒保存一次图像
            current_time = time.time()
            if current_time - last_save_time >= save_interval:
                save_image(frame, client_dir)
                last_save_time = current_time

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    except ConnectionResetError as e:
        print(f"连接中断: {e}")
    finally:
        conn.close()

    cv2.destroyAllWindows()

def recvall(sock, count):
    buf = b''
    while count:
        newbuf = sock.recv(count)
        if not newbuf:
            return None
        buf += newbuf
        count -= len(newbuf)
    return buf

def save_image(frame, client_dir):
    # 生成唯一的文件名（基于时间戳）
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    filename = f"received_image_{timestamp}.jpg"
    file_path = os.path.join(client_dir, filename)

    cv2.imwrite(file_path, frame)
    print(f"保存图像成功: {file_path}")

def server_program():
    host = socket.gethostname()  # 获取主机名
    host_ip = socket.gethostbyname(host)  # 获取主机的IP地址
    port = 5050

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(5)  # 监听多个连接

    print(f"服务器已启动，在 {host}({host_ip}),:{port} 监听...")

    while True:
        conn, addr = server_socket.accept()
        threading.Thread(target=handle_client, args=(conn, addr)).start()

if __name__ == '__main__':
    server_program()